<template>
  <a-select
    :value="arrayValue"
    @change="onChange"
    :disabled="disabled"
    mode="multiple"
    style="min-width: 200px"
    :placeholder="placeholder"
    :getPopupContainer="getParentContainer"
    optionFilterProp="children"
    :filterOption="false"
    @search="debouncedHandleSearch"
    @popupScroll="handlePopupScroll"
    allowClear
    :notFoundContent="loading ? '加载中...' : '无数据'"
    :showSearch="true"
  >
    <a-select-option v-for="(item, index) in dictOptions" :key="index" :value="item.value">
      <span style="display: inline-block; width: 100%" :title="item.label">
        {{ item.label }}
      </span>
    </a-select-option>
  </a-select>
</template>

<script>
import { getAction } from '@/api/manage'
import debounce from 'lodash/debounce'

export default {
  name: 'JMultiSelectTag',
  props: {
    placeholder: String,
    disabled: Boolean,
    value: String,
    type: String,
    valueField: {
      type: String,
      required: false,
      default: 'value',
    },
    spliter: {
      type: String,
      required: false,
      default: ',',
    },
    popContainer: {
      type: String,
      default: '',
      required: false,
    },
  },
  data() {
    return {
      dictOptions: [],
      tagType: '',
      url: '/report5/school',
      searchValue: '',
      arrayValue: !this.value ? [] : this.value.split(this.spliter),
      currentPage: 1, // 当前页码
      pageSize: 10, // 每页记录数
      total: 0, // 总记录数
      loading: false, // 是否正在加载数据
      isFetching: false, // 是否在进行数据请求，防止重复加载
    }
  },
  created() {
    // 获取字典数据
    this.initDictData()

    // 绑定防抖后的搜索方法
    this.debouncedHandleSearch = debounce(this.handleSearch, 300)
  },
  watch: {
    value(val) {
      if (!val) {
        this.arrayValue = []
      } else {
        this.arrayValue = val.split(this.spliter)
      }
    },
  },
  methods: {
    initDictData(reset = false) {
      if (reset) {
        this.currentPage = 1
        this.dictOptions = []
        this.total = 0
      }

      // 如果已经加载完全部数据，则不再加载
      if (this.currentPage > Math.ceil(this.total / this.pageSize) && this.total !== 0) {
        return
      }

      if (this.isFetching) return // 防止重复请求
      this.loading = true
      this.isFetching = true

      let data = {
        search: this.searchValue,
        pageNo: this.currentPage,
        pageSize: this.pageSize,
      }

      getAction(this.url, data)
        .then((res) => {
          if (res.code === 200) {
            const newRecords = res.result.records.map((e) => ({
              label: e.schoolName,
              value: e.schoolName,
            }))
            this.dictOptions = reset ? newRecords : [...this.dictOptions, ...newRecords]
            this.total = res.result.total // 假设返回的数据中包含总记录数
            this.currentPage += 1
          } else {
            // 处理错误情况
            this.$message.error(res.message || '加载数据失败')
          }
        })
        .finally(() => {
          this.loading = false
          this.isFetching = false
        })
    },
    handleSearch(value) {
      this.searchValue = value
      this.initDictData(true) // 重置数据并加载第一页
    },
    handlePopupScroll({ target }) {
      const { scrollTop, scrollHeight, clientHeight } = target
      // 当滚动高度超过90%时加载下一页
      if (scrollTop + clientHeight >= scrollHeight * 0.9) {
        if (!this.loading && this.dictOptions.length < this.total) {
          this.initDictData()
        }
      }
    },
    onChange(selectedValue) {
      this.$emit('change', selectedValue.join(this.spliter))
    },
    getParentContainer(node) {
      if (!this.popContainer) {
        return node.parentNode
      } else {
        return document.querySelector(this.popContainer)
      }
    },
    filterOption(input, option) {
      // 关闭本地过滤，使用服务器端过滤，所以这里可以返回 false 或者不需要
      return false
    },
  },
  beforeDestroy() {
    // 清理防抖函数
    if (this.debouncedHandleSearch && this.debouncedHandleSearch.cancel) {
      this.debouncedHandleSearch.cancel()
    }
  },
  model: {
    prop: 'value',
    event: 'change',
  },
}
</script>
